﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RaytracerLib.MathLib;
using TomanuExtensions;
using System.Diagnostics;
using RaytracerLib.Rays;
using RaytracerLib.Lights;

namespace RaytracerLib.ShadowTesters
{
    public class AttenuationShadowTester : ShadowTester
    {
        public AttenuationShadowTester(Scene a_scene)
            : base(a_scene)
        {
        }

        public override ColorFloat ShadowTest(Intersection a_source_ray_intersection, ShadowRay a_ray, 
            Light a_light)
        {
            m_scene.Statistics.ShadowTests++;

            if (a_ray.Depth >= m_max_ray_depth)
            {
                m_scene.Statistics.RaysToDepth++;
                return ColorFloat.Black;
            }

            Intersection intersection = a_source_ray_intersection;
            ColorFloat result = a_light.Color;
            double dist = 0;

            for (; ; )
            {
                intersection = m_scene.SpatialSubdivisioner.HitTest(intersection, a_ray);

                dist = (a_light.Pos - a_ray.Start).Length;

                if (intersection.Dist > dist)
                {
                    if (a_light.EnvironmentAttenuation != null)
                        result = a_light.EnvironmentAttenuation.Attenuate(result, dist);

                    return result;
                }

                if (!intersection.Material.HasRefraction)
                    return ColorFloat.Black;

                if (intersection.InnerAttenuation != null)
                    result = intersection.InnerAttenuation.Attenuate(result, intersection.Dist);

                a_ray = new ShadowRay(intersection, a_ray.Dir, RaySurfaceSide.RefractedSide);
            }
        }
    }
}
